package com.own.core.html.component;

import java.lang.reflect.Constructor;

import org.apache.wicket.extensions.breadcrumb.IBreadCrumbModel;
import org.apache.wicket.extensions.breadcrumb.panel.BreadCrumbPanel;
import org.apache.wicket.extensions.breadcrumb.panel.IBreadCrumbPanelFactory;

import com.own.core.html.panel.OwnPanel;

public class OwnBreadCrumbPanelFactory 
{
	private static final long serialVersionUID = 1L;

	/** Class to construct. */
	private final Class<? extends OwnPanel> panelClass;

	/**
	 * Construct.
	 * 
	 * @param panelClass
	 *            The class to use for creating instances. Must be of type {@link BreadCrumbPanel},
	 *            and must have constructor
	 *            {@link BreadCrumbPanel#BreadCrumbPanel(String, IBreadCrumbModel)}
	 */
	public OwnBreadCrumbPanelFactory(final Class<? extends OwnPanel> panelClass)
	{
		if (panelClass == null)
		{
			throw new IllegalArgumentException("argument panelClass must be not null");
		}

		if (!OwnPanel.class.isAssignableFrom(panelClass))
		{
			throw new IllegalArgumentException("argument panelClass (" + panelClass +
				") must extend class " + BreadCrumbPanel.class.getName());
		}


		this.panelClass = panelClass;

		// check whether it has the proper constructor
		getConstructor();
	}

	/**
	 * @see org.apache.wicket.extensions.breadcrumb.panel.IBreadCrumbPanelFactory#create(java.lang.String,
	 *      org.apache.wicket.extensions.breadcrumb.IBreadCrumbModel)
	 */
	public  OwnPanel create(String componentId, IBreadCrumbModel breadCrumbModel)
	{
		Constructor<? extends OwnPanel> ctor = getConstructor();
		try
		{
			return ctor.newInstance(new Object[] { componentId, breadCrumbModel });
		}
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}
	}

	/**
	 * Gets the proper constructor of the panel class.
	 * 
	 * @return The constructor.
	 */
	private final Constructor<? extends OwnPanel> getConstructor()
	{
		try
		{
			Constructor<? extends OwnPanel> ctor = panelClass.getConstructor(new Class[] {
					String.class, IBreadCrumbModel.class });
			return ctor;
		}
		catch (SecurityException e)
		{
			throw new RuntimeException(e);
		}
		catch (NoSuchMethodException e)
		{
			throw new RuntimeException(e);
		}
	}
}
